<?php
/**
 * coreRouterMapSegment
 *
 * 라우팅 맵 - Segment 방식
 *
 * @package router
 * @author  Platform Team
 */

class coreRouterMapSegment extends coreRouterMapAbstract
{
    const KEY_CONTROLLER = 'controller';
    const KEY_METHOD = 'method';
    const KEY_PARAM = 'params';

    /**
     * Map Parse
     */
    public function parse()
    {
        $sPathInfo = $this->parsePathInfo();

        if (!empty($this->aMap)) {
            $result = $this->parseMap($sPathInfo);
        }

        if ($result) return;

        $this->parseDefault($sPathInfo);
    }

    /**
     * PATH_INFO 반환
     *
     * @return string
     */
    private function parsePathInfo()
    {
        if ($this->isFixCgiPathinfo !== true) {
            return $_SERVER['PATH_INFO'];
        }

        if (empty($_SERVER['ORIG_PATH_TRANSLATED'])) {
            return $_SERVER['PATH_INFO'];
        }

        $sScriptFile    = $this->prettyPath($_SERVER['SCRIPT_FILENAME']);
        $sPathTranslate = $this->prettyPath($_SERVER['ORIG_PATH_TRANSLATED']);

        $sResult        = str_replace($sScriptFile, '', $sPathTranslate);

        return $sResult;
    }

    /**
     * OS 별 디렉토리 구분자가 달라서 구분문자를 통일 시키기 위한 메소드
     */
    private function prettyPath($sPath)
    {
        return preg_replace('@[/\\\]+@', '/', $sPath);
    }

    /**
     * 정의된 맵 규칙에 따른 파싱
     *
     * @param string $sPathInfo
     * @return boolean
     */
    private function parseMap($sPathInfo)
    {
        $result = false;

        foreach ($this->aMap as $key=>$aMap) {
            if (!$aMap[self::KEY_CONTROLLER]) continue;

            $regex = '#' . $key . '#';

            if (preg_match($regex, $sPathInfo, $aMatch) === 0) continue;

            array_shift($aMatch);
            $count = count($aMatch);

            //치환시켜야 하는 역매치 값이 존재하는 경우
            if ($count > 0) {
                $this->replaceDeep($sPathInfo, $regex, $aMap);
            }

            $result = $this->parsePath($aMap[self::KEY_CONTROLLER]);

            if ($result === false) {
                continue;
            }

            $this->sController = $result['controller'];
            $this->sControllerPath = $result['path'];
            $this->sMethod = $aMap[self::KEY_METHOD] ? $aMap[self::KEY_METHOD] : FW_ROUTE_DEFAULT_METHOD;
            $this->aMethodParam = !empty($aMap[self::KEY_PARAM]) ? $aMap[self::KEY_PARAM] : false;

            return true;
        }

        return ($result === false) ? false : true;
    }

    /**
     * 기본 규칙에 따른 파싱
     *
     * @param string $sPathInfo
     * @return boolean
     */
    private function parseDefault($sPathInfo)
    {
        //PATH_INFO 에 / 만 들어오는 경우의 예외처리를 위함
        $sPathInfo = $this->stripFirstSlashes($sPathInfo);

        $result = $this->parsePath($sPathInfo, -1);

        if ($result === false) {
            $this->sErrorMsg = 'Controller parse error : ' . $sPathInfo;
            return false;
        }

        $this->sController = $result['controller'];
        $this->sControllerPath = $result['path'];
        $this->sMethod = $result['method'];

        return true;
    }

}
